using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CueMulti : MonoBehaviour
{
    static float TAU = 2 * Mathf.PI;

    public GameObject arrow;

    public Vector3 firstClick;

    public float force;

    public enum RollingState { Rolling, HitSomething };
    RollingState rollingState;
    public enum MovingState { Moving, Halted };
    MovingState movingState;

    Rigidbody2D rb;
    LineRenderer lr;
    GameStateMulti game;
    bool ignoreOneFrame;
    float oldSpeed;

    // Use this for initialization
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        lr = GetComponent<LineRenderer>();
        game = FindObjectOfType<GameStateMulti>();
        rollingState = RollingState.HitSomething;
        movingState = MovingState.Halted;
        ignoreOneFrame = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (game.gameOver)
            return;

        if (rollingState == RollingState.Rolling && rb.velocity.sqrMagnitude <= 0.01f && oldSpeed > rb.velocity.sqrMagnitude)
        {
            game.SetPenaltyText("Came to a halt without hitting anything. 2 shots.");
            game.AddPenalty();
            rollingState = RollingState.HitSomething;
        }
        if (movingState == MovingState.Moving && rb.velocity.sqrMagnitude <= 0.01f && oldSpeed > rb.velocity.sqrMagnitude)
        {
            movingState = MovingState.Halted;
            game.BallHalted();
        }
        oldSpeed = rb.velocity.sqrMagnitude;

        ignoreOneFrame = false;

        if (Input.GetMouseButtonDown(0))
        {
            firstClick = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        }
        if (Input.GetMouseButton(0) || Input.GetMouseButtonUp(0))
        {
            if (rb.velocity.sqrMagnitude > 0.01) return;

            Vector3 mousePoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePoint.z = 0;

            Vector3 difference = firstClick - mousePoint;

            difference *= 0.5f;

            float angleFromCue = Mathf.Atan2(difference.y, difference.x);
            angleFromCue *= Mathf.Rad2Deg;

            float angleFromCentre = Mathf.Atan2(transform.position.y, transform.position.x);
            angleFromCentre *= Mathf.Rad2Deg;

            float theAngle = angleFromCue - angleFromCentre;
            while (theAngle < 0.0f)
                theAngle += 360.0f;
            while (theAngle > 360.0f)
                theAngle -= 360.0f;

            if (theAngle > 0.0f && theAngle < 180.0f)
            {
                arrow.GetComponent < Renderer >().enabled = false;
                lr.enabled = false;
                return;
            }

            arrow.transform.position = transform.position + difference;
            arrow.transform.eulerAngles = new Vector3(0, 0, angleFromCue - 90);
            arrow.GetComponent < Renderer >().enabled = true;
            lr.enabled = true;
            lr.SetPosition(0, transform.position);
            lr.SetPosition(1, arrow.transform.position);
            lr.alignment = LineAlignment.TransformZ;

            if (Input.GetMouseButtonUp(0))
            {
                Vector2 f = new Vector2(difference.x, difference.y);
                f *= force;
                rb.AddForce(f);
                rollingState = RollingState.Rolling;
                movingState = MovingState.Moving;
                game.ShotShotted();
                ignoreOneFrame = true;
                game.SetPenaltyText("");
            }
        }
        else
        {
            arrow.GetComponent < Renderer >().enabled = false;
            lr.enabled = false;
        }
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (rollingState != RollingState.Rolling) return;

        var obj = collision.collider.gameObject;
        BallColour ball = obj.GetComponent<BallColour>();
        if (!ball) return;

        rollingState = RollingState.HitSomething;

        if (ball.colour == game.GetUnfriendlyColour())
        {
            game.SetPenaltyText("Hit a " + ((ball.colour == BallColour.Colour.Yellow) ? "yellow" : "red") +" ball first. 2 shots.");
            game.AddPenalty();
        }
        else if (ball.colour == BallColour.Colour.Black)
        {
            var balls = FindObjectsOfType<BallColour>();
            bool stillRedBalls = false;
            foreach (BallColour otherball in balls)
            {
                if (otherball.colour == game.GetFriendlyColour())
                {
                    stillRedBalls = true;
                    break;
                }
            }
            if (false == stillRedBalls) return;
            game.SetPenaltyText("Hit the black first. 2 shots.");
            game.AddPenalty();
        }
    }

    void DrawLine(Vector3 start, Vector3 end)
    {
        GameObject myLine = new GameObject();
        myLine.transform.position = start;
        myLine.AddComponent<LineRenderer>();
    }

    public void Removed()
    {
        game.Potted(BallColour.Colour.White);
        rollingState = RollingState.HitSomething;

        GetComponent<MeshRenderer>().enabled = false;
        transform.position = new Vector3(0,2.5f,0);
        rb.velocity = Vector3.zero;
        StartCoroutine("PutBack");
    }

    IEnumerator PutBack()
    {
        yield return new WaitForSeconds(0.75f);
        GetComponent<MeshRenderer>().enabled = true;
        transform.position = new Vector3(0,2.5f,0);
        rb.velocity = Vector3.zero;
    }
}
